﻿//使用ORB算子进行特征点检测和匹配

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>


using namespace cv;
using namespace std;

int main()
{
	Mat church = imread("E:\\VC_project\\figure\\church.jpg");
	Mat chess = imread("E:\\VC_project\\figure\\chess.jpg");
	Mat lena = imread("E:\\VC_project\\figure\\lena.jpg");
	
	double t = getTickCount();//当前滴答数
	if (chess.empty() || chess.empty() || lena.empty())
	{
		cout << "图片读取失败！" << endl;
		return -1;
	}

	//对图像进行旋转变化
	Mat lena90;
	transpose(lena, lena90);
	flip(lena90, lena90, 1);

	//对图像进行灰度处理
	Mat graychurch, graychess, grayLena, grayLena90;
	cvtColor(church, graychurch, COLOR_BGR2GRAY);
	cvtColor(chess, graychess, COLOR_BGR2GRAY);
	cvtColor(lena, grayLena, COLOR_BGR2GRAY);
	cvtColor(lena90, grayLena90, COLOR_BGR2GRAY);

	//创建ORB算子
	Ptr<ORB> orb = ORB::create();
	vector<KeyPoint> keypoints1, keypoints2, keypoints3, keypoints4;//用于存放特征点
	Mat descriptors1, descriptors2;//用于存放描述子向量

	//使用ORB算子检测chess和church特征点
	orb->detect(graychurch, keypoints1);
	orb->detect(graychess, keypoints2);

	//在原图中绘制特征点
	drawKeypoints(church, keypoints1, church, Scalar(0, 0, 255));
	drawKeypoints(chess, keypoints2, chess, Scalar(0, 0, 255));

	t = ((double)getTickCount() - t) / getTickFrequency();
	cout << "算法用时：" << t << "秒" << endl;// t=1.485s

	//使用ORB算子检测lena的特征点和描述子向量
	orb->detectAndCompute(grayLena, Mat(), keypoints3, descriptors1);
	orb->detectAndCompute(grayLena90, Mat(), keypoints4, descriptors2);

	//实例化BFM匹配器
	BFMatcher matcher;

	//DMatch是用来描述匹配好的一对特征点的类，包含这两个点之间的匹配信息
	vector<DMatch> matches;

	//对特征向量进行匹配
	matcher.match(descriptors1, descriptors2, matches);

	//画出匹配图
	Mat imgMatches;
	drawMatches(lena, keypoints3, lena90, keypoints4, matches, imgMatches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

	imshow("ORB_chess角点检测", chess);
	imshow("ORB_church角点检测", church);
	imshow("ORB_lena角点匹配", imgMatches);
	waitKey();


}


